/*

 Copyright (c) 2008-2009 Fabrizio Pistonesi

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 */

#include "patch.h"

//SKYBOX-SLIDE
Patch::Patch(IrrlichtDevice *device, stringc image, bool visible, f32 x, f32 y, f32 w, f32 h, int face, SColor color)
{
  Image = image; //serialize
  X = x;
  Y = y;
  W = w;
  H = h;
  Color = color;
  Face = face;

  Device = device;
  PatchRotation = Device->getSceneManager()->addEmptySceneNode();
  PatchRotation->setIsDebugObject(true);
  PatchCube = Device->getSceneManager()->addCubeSceneNode(1,PatchRotation);
  PatchCube->setIsDebugObject(true);
  IsVisible = visible;
  Texture = Device->getVideoDriver()->getTexture(image.c_str());

  PatchCube->setMaterialTexture(0, Texture);
  PatchCube->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);
  PatchCube->setMaterialFlag(EMF_ANISOTROPIC_FILTER, true);
  PatchCube->getMaterial(0).EmissiveColor = color;
  PatchCube->setMaterialFlag(EMF_ZBUFFER,false);

  if (w == -1)
    W = (f32)(Texture->getSize().Width * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Width); //a.viarengo added cast
  if (h == -1)
    H = (f32)(Texture->getSize().Height * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Height); //a.viarengo added cast

  PatchCube->setScale(vector3df(W,H,0));

  PatchCube->setPosition(vector3df(-50+W/2+X, 50-H/2-Y, 50));

  switch (face)
    {
  case 1: //irr=top, ey=front
    PatchRotation->setRotation(vector3df(0, 0, 0));
    break;
  case 2: //irr=bottom, ey=right
    PatchRotation->setRotation(vector3df(0, 90, 0));
    break;
  case 3: //irr=left, ey=back
    PatchRotation->setRotation(vector3df(0, 180, 0));
    break;
  case 4: //irr=right, ey =left
    PatchRotation->setRotation(vector3df(0, 270, 0));
    break;
  case 5: //irr=front, ey=top
    PatchRotation->setRotation(vector3df(270, 0, 0));
    break;
  case 6: //irr=back, ey=bottom
    PatchRotation->setRotation(vector3df(0, 90, 0));
    break;
  default:
    break;
    }
  if (!IsVisible)
    PatchCube->setVisible(false);
}

//SKYDOME
Patch::Patch(IrrlichtDevice *device, stringc image, bool visible, f32 az,f32 el, f32 w, f32 h, SColor color)
{
  Image = image; //serialize
  Az = az;
  El = el;
  W = w;
  H = h;
  Color = color;

  Device = device;
  PatchRotation = Device->getSceneManager()->addEmptySceneNode();
  PatchRotation->setIsDebugObject(true);
  PatchCube = Device->getSceneManager()->addCubeSceneNode(1, PatchRotation);
  PatchCube->setIsDebugObject(true);
  IsVisible = visible;
  if (!Device->getFileSystem()->existFile(image.c_str()))
    {
      Device->getLogger()->log("Could not find the image: %S", image.c_str());
      image = "missing.png";
    }
  else
    {
      Texture = Device->getVideoDriver()->getTexture(image.c_str());
    }
  PatchCube->setMaterialTexture(0, Texture);
  PatchCube->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);
  PatchCube->setMaterialFlag(EMF_LIGHTING, true);
  PatchCube->setMaterialFlag(EMF_ANISOTROPIC_FILTER, true);
  PatchCube->setMaterialFlag(EMF_ZBUFFER,false);
  PatchCube->getMaterial(0).EmissiveColor = color;

  if (w == -1)
    W = (f32)(Texture->getSize().Width * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Width); //a.viarengo added cast
  if (h == -1)
    H = (f32)(Texture->getSize().Height * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Height); //a.viarengo added cast

  PatchCube->setScale(vector3df(W, H, 0));
  PatchCube->setPosition(vector3df(0, 0, 50.0f));
  PatchRotation->setRotation(vector3df(el, az, 0));
}

//PANEL
Patch::Patch(IrrlichtDevice *device, IGUIElement *parent, bool visible,
    stringc image, s32 x, s32 y, s32 w, s32 h, SColor color)
{
  Device = device;
  Image = image; //serialize
  X = (f32)x; //a.viarengo added cast
  Y = (f32)y; //a.viarengo added cast
  W = (f32)w; //a.viarengo added cast
  H = (f32)h; //a.viarengo added cast
  Color = color;
  IsVisible = visible;

  if (!Device->getFileSystem()->existFile(image.c_str()))
    {
      Device->getLogger()->log("Could not find the image: ", image.c_str());
      image = "missing.png";
    }
  else
    {
      Texture = Device->getVideoDriver()->getTexture(image.c_str());
    }

  if (w == -1) W = (f32)Texture->getSize().Width;
  if (h == -1) H = (f32)Texture->getSize().Height;
  PatchPanel = Device->getGUIEnvironment()->addImage(Texture, position2d<s32>(X,Y), true, parent);
  PatchPanel->setColor(color);
  PatchPanel->getParent()->getParent()->bringToFront(PatchPanel->getParent());
}

Patch::~Patch()
{

}

//SKYBOX-SLIDE
void
Patch::move(f32 x, f32 y, f32 w, f32 h, int face)
{
  x = x * 100 / Device->getVideoDriver()->getScreenSize().Width;
  y = y * 100 / Device->getVideoDriver()->getScreenSize().Height;
  w = w * 100 / Device->getVideoDriver()->getScreenSize().Width;
  h = h * 100 / Device->getVideoDriver()->getScreenSize().Height;
  if (w == -1)
    w = (f32)(Texture->getSize().Width * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Width); //a.viarengo added cast
  if (h == -1)
    h = (f32)(Texture->getSize().Height * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Height); //a.viarengo added cast
  PatchCube->setScale(vector3df(w, h, 0));
  PatchCube->setPosition(vector3df(-50.0f + w / 2 + x, 50.0f - h / 2 - y, 50.0f));
  switch (face)
    {
  case 1: //irr=top, ey=front
    PatchRotation->setRotation(vector3df(0, 0, 0));
    break;
  case 2: //irr=bottom, ey=right
    PatchRotation->setRotation(vector3df(0, 90, 0));
    break;
  case 3: //irr=left, ey=back
    PatchRotation->setRotation(vector3df(0, 180, 0));
    break;
  case 4: //irr=right, ey =left
    PatchRotation->setRotation(vector3df(0, 270, 0));
    break;
  case 5: //irr=front, ey=top
    PatchRotation->setRotation(vector3df(270, 0, 0));
    break;
  case 6: //irr=back, ey=bottom
    PatchRotation->setRotation(vector3df(0, 90, 0));
    break;
  default:
    break;
    }
}

//SKYDOME
void
Patch::move(f32 az, f32 el, f32 w, f32 h)
{
  //s32 x = x * 100 / Device->getVideoDriver()->getScreenSize().Width;
  //s32 y = y * 100 / Device->getVideoDriver()->getScreenSize().Height;
  w = w * 100 / Device->getVideoDriver()->getScreenSize().Width;
  h = h * 100 / Device->getVideoDriver()->getScreenSize().Height;
  if (w == -1)
    w = (f32)(Texture->getSize().Width * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Width); //a.viarengo added cast
  if (h == -1)
    h = (f32)(Texture->getSize().Height * 100) / (f32)(Device->getVideoDriver()->getScreenSize().Height); //a.viarengo added cast
  PatchRotation->setRotation(vector3df(el, az, 0));
  PatchCube->setScale(vector3df(w, h, 0));
}

//PANEL
void
Patch::move(s32 x, s32 y, s32 w, s32 h)
{
  dimension2d<u32> size = Texture->getSize();
  PatchPanel->setRelativePosition(rect<s32> (x, y, x + size.Width, y
      + size.Height));
  if (w != -1 && h != -1)
    PatchPanel->setRelativePosition(rect<s32> (x, y, x + w, y + h));
}

void
Patch::setColor(SColor color)
{
  if (PatchCube)
    PatchCube->getMaterial(0).EmissiveColor = color;
  if (PatchPanel)
    PatchPanel->setColor(color);

  Color = color; //serialize
}

void
Patch::setImage(const c8 *image)
{
  Image = image; //serialize

  if (!Device->getFileSystem()->existFile(image))
    {
      Device->getLogger()->log("Could not find the image: ", image);
      image = "missing.png";
    }
  if (PatchCube)
    PatchCube->setMaterialTexture(1, Texture);
  if (PatchPanel)
    PatchPanel->setImage(Texture);
}

void
Patch::setVisible(bool visible)
{
  if (PatchCube)
    PatchCube->setVisible(visible);
  if (PatchPanel)
    PatchPanel->setVisible(visible);
}

bool
Patch::isVisible()
{
  if (PatchCube)
    return PatchCube->isVisible();
  if (PatchPanel)
    {
      return PatchPanel->isVisible();
    }
  else
    {
      return true;
    }
}

//SKYBOX
void
Patch::rotate(vector3df rotation)
{
  PatchCube->setRotation(rotation);
  Rotation = rotation; // serialize
}

void
Patch::serialize(IAttributes* attributes)
{
  attributes->addString("image", Image.c_str());
  attributes->addFloat("x", X);
  attributes->addFloat("y", Y);
  attributes->addFloat("w", W);
  attributes->addFloat("h", H);
  attributes->addFloat("az", Az);
  attributes->addFloat("el", El);
  attributes->addInt("face", Face);
  attributes->addColor("color", Color);
  attributes->addVector3d("rotation", Rotation);
  attributes->addBool("visible", IsVisible);
}
